package driver

import (
	"context"
	"fmt"
	"github.com/chicken-team-outside/chicken_transmission/api_messages"
	"github.com/chicken-team-outside/chicken_transmission/model"
	"github.com/pkg/errors"
	"io"
	"io/fs"
	"os"
)

type FileInfo struct {
	Name  string `json:"name"`
	Size  int64  `json:"size"`
	IsDir bool   `json:"is_dir"`
	Mtime int64  `json:"mtime"`
}

func (f FileInfo) String() string {
	return fmt.Sprintf("{Name:\"%s\", Size:%d, Mtime:%d, IsDir:%v}",
		f.Name,
		f.Size,
		f.Mtime,
		f.IsDir,
	)
}

var ErrUnSupported = errors.New("unsupported")

func VendorDesc(vendor model.Vendor) string {
	switch vendor {
	case model.Vendor_Local:
		return "本地磁盘"
	case model.Vendor_SMB2:
		return "SMB2"
	case model.Vendor_BaiduNetDisk:
		return "百度网盘"
	case model.Vendor_ChaoXingNetDisk:
		return "超星云盘"
	default:
		return fmt.Sprintf("UnkownVendor(%d)", vendor)
	}
}

func VendorAvailable(v model.Vendor) bool {
	return v == model.Vendor_Local || v == model.Vendor_SMB2 || v == model.Vendor_BaiduNetDisk
}

type GetVendor interface {
	GetVendor() model.Vendor
}

type NetDiskDriver interface {
	UploadFile(ctx context.Context, size int64, destPath string, file io.ReadSeeker) error
	GetFileDownloadLink(ctx context.Context, destPath string) (*api_messages.LinkInfo, error)
	MkdirAll(ctx context.Context, path string) error
	Exists(ctx context.Context, path string) (bool, error)
	Remove(ctx context.Context, targetPath string) error
	io.Closer
	GetVendor() model.Vendor
	UserName(ctx context.Context) (string, error)
	GetQuota(ctx context.Context) (used, total int64, err error)
	ListDir(ctx context.Context, path string) ([]*FileInfo, error)
}

type LocalDriverFile interface {
	io.Closer
	io.Reader
	io.Seeker
	io.Writer
	Stat() (fs.FileInfo, error)
}

type LocalDriver interface {
	Stat(name string) (os.FileInfo, error)
	OpenFile(path string, flag int, mode os.FileMode) (LocalDriverFile, error)
	MkdirAll(path string, perm os.FileMode) error
	Remove(path string) error
	Rename(oldPath string, newPath string) error
	ListFiles(dirPath string) ([]os.FileInfo, error)
	Truncate(path string, size int64) error
	GetVendor() model.Vendor
	io.Closer
}
